package cn.steel.service.impl;

import cn.steel.domain.entity.EmailLog;
import cn.steel.domain.entity.SupplierInfo;
import cn.steel.domain.entity.User;
import cn.steel.mapper.EmailLogMapper;
import cn.steel.service.EmailService;
import cn.steel.service.OrderService;
import cn.steel.service.SupplierInfoService;
import cn.steel.service.UserService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import jakarta.mail.internet.MimeMessage;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Random;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
@RequiredArgsConstructor
public class EmailServiceImpl implements EmailService {

    private final JavaMailSender mailSender;
    private final TemplateEngine templateEngine;
    private final UserService userService;
    private final SupplierInfoService supplierInfoService;
    private final OrderService orderService;
    private final EmailLogMapper emailLogMapper;
    private final RedisTemplate<String, Object> redisTemplate;

    private static final String EMAIL_SENT_KEY = "email:sent:supplier:";
    private static final String[] ENCOURAGE_MESSAGES = {
            "您的订单表现非常出色，继续保持，未来可期！",
            "您的评级显示了您的实力，期待您带来更多优质产品！",
            "每笔订单都是信任的体现，感谢您的努力！",
            "您的贡献让平台更加精彩，继续加油！"
    };

    @PostConstruct
    public void init() {
        redisTemplate.opsForValue().setIfAbsent("email:scheduler:enabled", true);
        log.info("Initialized email:scheduler:enabled to true in Redis");
    }

    @Override
    @Scheduled(cron = "${email.scheduler.cron}")
    public void sendWeeklySupplierEmail() {
        log.info("Weekly email task triggered at {}", LocalDateTime.now());
        Object enabled = redisTemplate.opsForValue().get("email:scheduler:enabled");
        log.debug("Redis email:scheduler:enabled = {}", enabled);
        if (!(Boolean.TRUE.equals(enabled) || "true".equals(enabled))) {
            log.info("Weekly email scheduler is disabled");
            return;
        }

        List<User> suppliers = userService.findUsersByRole("SUPPLIER");
        log.info("Found {} suppliers to process", suppliers.size());
        if (suppliers.isEmpty()) {
            log.warn("No suppliers found with role SUPPLIER");
        }

        for (User supplier : suppliers) {
            String redisKey = EMAIL_SENT_KEY + supplier.getId();
            if (Boolean.TRUE.equals(redisTemplate.hasKey(redisKey))) {
                log.info("Email already sent to supplierId={} this week", supplier.getId());
                continue;
            }

            try {
                log.debug("Preparing email for supplierId={}, email={}", supplier.getId(), supplier.getEmail());
                SupplierInfo supplierInfo;
                try {
                    supplierInfo = supplierInfoService.getSupplierInfoByUserId(supplier.getId());
                } catch (IllegalArgumentException e) {
                    log.warn("跳过供应商Id={}，原因：{}", supplier.getId(), e.getMessage());
                    continue;
                }
                if (supplierInfo == null) {
                    log.warn("No supplier info found for supplierId={}", supplier.getId());
                    continue;
                }
                long orderCount = orderService.countOrdersBySupplierId(supplier.getId());
                String encourageMessage = getRandomEncourageMessage(supplierInfo.getAverageRating());

                Context context = new Context();
                context.setVariable("supplierName", supplierInfo.getCompany());
                context.setVariable("orderCount", orderCount);
                context.setVariable("rating", supplierInfo.getAverageRating());
                context.setVariable("encourageMessage", encourageMessage);

                log.debug("Attempting to resolve template: email/weekly_supplier");
                String htmlContent = templateEngine.process("email/weekly_supplier", context);
                log.debug("Template resolved successfully");

                MimeMessage message = mailSender.createMimeMessage();
                MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");
                helper.setFrom("1959450565@qq.com");//发件人
                helper.setTo(supplier.getEmail());
                helper.setSubject("每周订单与评级报告 - 钢域云贸");
                helper.setText(htmlContent, true);

                mailSender.send(message);

                EmailLog emailLog = new EmailLog();
                emailLog.setRecipientId(supplier.getId());
                emailLog.setRecipientEmail(supplier.getEmail());
                emailLog.setSubject("每周订单与评级报告 - 钢域云贸");
                emailLog.setContent(htmlContent);
                emailLog.setStatus("SUCCESS");
                emailLog.setCreateTime(LocalDateTime.now());
                emailLogMapper.insertEmailLog(emailLog);

                redisTemplate.opsForValue().set(redisKey, true, 7, TimeUnit.DAYS);
                log.info("Email sent to supplierId={}, email={}", supplier.getId(), supplier.getEmail());

            } catch (Exception e) {
                EmailLog emailLog = new EmailLog();
                emailLog.setRecipientId(supplier.getId());
                emailLog.setRecipientEmail(supplier.getEmail());
                emailLog.setSubject("每周订单与评级报告 - 钢域云贸");
                emailLog.setContent("Error occurred");
                emailLog.setStatus("FAILED");
                emailLog.setErrorMessage(e.getMessage());
                emailLog.setCreateTime(LocalDateTime.now());
                emailLogMapper.insertEmailLog(emailLog);

                log.error("Failed to send email to supplierId={}: {}", supplier.getId(), e.getMessage(), e);
            }
        }
        log.info("Weekly email task completed");
    }

    private String getRandomEncourageMessage(Double rating) {
        Random random = new Random();
        String message = ENCOURAGE_MESSAGES[random.nextInt(ENCOURAGE_MESSAGES.length)];
        if (rating >= 4.0) {
            return "卓越的您，" + message;
        } else if (rating >= 3.0) {
            return "优秀的您，" + message;
        } else {
            return "努力的您，" + message;
        }
    }
}